package com.cqit.bluetoothkeybox.service.impl;

import com.cqit.bluetoothkeybox.common.WxUrlConstant;
import com.cqit.bluetoothkeybox.config.WechatConfig;
import com.cqit.bluetoothkeybox.dto.wechat.WechatAccessToken;
import com.cqit.bluetoothkeybox.dto.wechat.WechatUserOpenId;
import com.cqit.bluetoothkeybox.service.WechatService;
import com.cqit.bluetoothkeybox.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@Service
public class WechatServiceImpl implements WechatService {

    @Autowired
    private WechatConfig wechatConfig;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public String getOpenId(String authCode) throws Exception {
        // redis 缓存有数据，则取用即可
        if (redisUtil.hasKey(authCode)) {
            return (String) redisUtil.get(authCode);
        }

        Map<String, String> data = new HashMap<>();
        data.put("appid", wechatConfig.getAppId());
        data.put("secret", wechatConfig.getSecret());
        data.put("js_code", authCode);
        data.put("grant_type", "authorization_code");

        //通过build方法获取核心类RestTemplate，提供了所拥有访问Rest服务的接口
        HttpHeaders headers = new HttpHeaders();

        //设置类型
        MediaType type = MediaType.parseMediaType("text/plain; charset=UTF-8");
        headers.setContentType(type);

        ResponseEntity<WechatUserOpenId> responseEntity = restTemplate.exchange(WxUrlConstant.LOGIN_URL + "?appid={appid}&secret={secret}&js_code={js_code}&grant_type={grant_type}"
                , HttpMethod.GET
                , new HttpEntity<String>(headers)
                , WechatUserOpenId.class
                , data);
        WechatUserOpenId body = responseEntity.getBody();
        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            throw new Exception(body == null ? "获取openid失败！" : body.getErrmsg());
        }

        assert body != null;
        redisUtil.set(authCode, body.getOpenid());
        redisUtil.expire(authCode, 7200);

        return body.getOpenid();
    }

    @Override
    public String getAccessToken() throws Exception {
        // redis 缓存有数据，则取用即可
        if (redisUtil.hasKey(wechatConfig.getAppId())) {
            return (String) redisUtil.get(wechatConfig.getAppId());
        }

        Map<String, String> data = new HashMap<>();
        data.put("appid", wechatConfig.getAppId());
        data.put("secret", wechatConfig.getSecret());

        //通过build方法获取核心类RestTemplate，提供了所拥有访问Rest服务的接口
        HttpHeaders headers = new HttpHeaders();

        //设置类型
        MediaType type = MediaType.parseMediaType("text/plain; charset=UTF-8");
        headers.setContentType(type);

        ResponseEntity<WechatAccessToken> responseEntity = restTemplate.exchange(WxUrlConstant.GET_ACCESS_TOKEN_URL + "&appid={appid}&secret={secret}"
                , HttpMethod.GET
                , new HttpEntity<String>(headers)
                , WechatAccessToken.class
                , data);
        WechatAccessToken body = responseEntity.getBody();
        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            throw new Exception(body == null ? "获取openid失败！" : body.getErrmsg());
        }

        assert body != null;
        redisUtil.set(wechatConfig.getAppId(), body.getAccess_token());
        redisUtil.expire(wechatConfig.getAppId(), 7200);

        return body.getAccess_token();
    }

    @Override
    public String getUnionid(String accessToken, String openId) throws Exception {
        Map<String, String> data = new HashMap<>();
        data.put("access_token", accessToken);
        data.put("openid", openId);

        //通过build方法获取核心类RestTemplate，提供了所拥有访问Rest服务的接口
        HttpHeaders headers = new HttpHeaders();

        //设置类型
        MediaType type = MediaType.parseMediaType("text/plain; charset=UTF-8");
        headers.setContentType(type);

        ResponseEntity<Map> responseEntity = restTemplate.exchange(WxUrlConstant.USER_INFO + "?access_token={access_token}&openid={openid}"
                , HttpMethod.GET
                , new HttpEntity<String>(headers)
                , Map.class
                , data);
        Map body = responseEntity.getBody();
        if (responseEntity.getStatusCode() != HttpStatus.OK || body == null) {
            throw new Exception(String.valueOf(body == null ? "获取unionid失败！" : body.get("errmsg")));
        }
        return (String) body.get("unionid");
    }
}
